function_name = ["lcase", "ucase", "print", "int", "float", "lineinput", "left","str",
                 "return","plus", "minus", "times", "divby","swap","arr","split","join","arrset","arrverse","arrget","mid",
                 "arrsort","shell"]
loops = ["while", "wend", "iftrue", "ifequal", "fig", "else", "for", "forin", "end"]
ud_functions = {}  # for user defined functions


def lex(line):
    part = []
    a = []

    forward_variable = -1
    forward_number = -1
    forward_string = -1

    for i in range(0, len(line)):
        part.append(line[i])

    for i in range(0, len(part)):  ## returns a set of tuples . each tuple has two values : type of data and the data.
        ## for ex : [("variable","x"), ("number","5")]



        if check_alpha(part[i][0]) == True:
            variable = analyze_data(i, line, "variable")  # extracting the variable from the string

            if variable not in function_name and not variable in ud_functions and variable not in loops and variable != 'function':
                if i > forward_variable:
                    a.append(("variable", variable))
                    forward_variable = i + len(variable) - 1
                    forward_number = i + len(variable) - 1
            if variable in function_name:
                if i > forward_variable:  ## changed here
                    a.append(("function", variable))
                    forward_variable = i + len(variable) - 1
            if variable in loops:
                if i > forward_variable:  ## changed here
                    a.append(("loop", variable))
                    forward_variable = i + len(variable) - 1
            if variable == 'function':
                if i > forward_variable:
                    a.append(("ud_function", 'ud_function'))
                    forward_variable = i + len(variable) - 1
            if variable in ud_functions:
                if i > forward_variable:
                    a.append(("function", variable))
                    forward_variable = i + len(variable) - 1

        if check_number(part[i]) == True:
            number = analyze_data(i, line, "number")
            if i > forward_number:
                a.append(("number", number))
                forward_number = i + len(number) - 1

        if part[i] == " ":
            pass

        if part[i] == '"':
            string = '"' + analyze_data(i + 1, line, "string") + '"'
            if i > forward_string:
                a.append(("string", string))
                forward_string = i + len(string) - 1
                forward_variable = i + len(string) - 1
                forward_number = i + len(string) - 1

    print(a)
    return a


## THIS FUNCTION EXTRACTS A VARIABLE OR A NUMBER FROM A STRING


def analyze_data(index, string, type):
    variable = ""
    if type == "variable":
        for i in range(index, len(string)):
            if check_alpha(string[i]) == True or check_number(string[i]) == True:
                variable += string[i]
            else:
                break

    if type == "number":
        for i in range(index, len(string)):
            if check_number(string[i]) == True:
                variable += string[i]
            else:
                break

    if type == "string":
        for i in range(index, len(string)):
            if string[i] != '"':
                variable += string[i]
            else:
                break

    return variable


def check_alpha(alpha):
    return_value = 0
    for i in range(65, 90):
        if alpha == chr(i) or alpha == chr(i + 32):
            return_value = True

    return return_value


def check_number(num):
    return_value = 0
    nums = "0123456789"
    if num in nums:
        return_value = True

    return return_value


# code = '''function hello string'''
# lex(code)

#############################################################PARSER#########################################################

from pavdef2 import *

outfile = open("ex.txt.py", "w")
file = open("ex.txt", "r")
outfile.write("from pavdef2 import* \n")
lines = file.readlines()
file.close()

arr = list()

# function_name = ["ucase", "print", "lcase","int","float","lineinput","left"]
loops = ["while", "wend", "iftrue", "ifequal", "fig", "else", 'for', "forin"]
functions = {"ucase": 0, "print": -1, "lcase": 0, "str": 0, "int": 0, "left": 1, "return" : -2,
             "plus":1, "minus":1, "times":1, "divby":1,"swap":-3,"arr":0,"arrverse":0,"arrget":2,"arrset":2,"mid":2,"arrsort":0,
             "shell":0}


def find_param(flist, nparam):
    arr = list()
    for i in range(nparam):
        arr.append(flist[i])
    return arr


def create_assign_var(var_name, assign_list):  ## creates variable assignment part
    after_equal = ""
    for i in range(len(assign_list)):
        after_equal += assign_list[i]
    output = var_name + " = " + after_equal
    return output


def create_func_var(var_name, func_list, indent):  ## used when functions are used
    # print ud_functions
    output = "\n"
    forward = 0
    # print ("hello",func_list)
    for i in range(len(func_list)):
        if func_list[i] in function_name:  ## for pre defined functions
            param_no = functions[func_list[i]]
            if param_no >= 0:  # subcall
                params = find_param(func_list[i + 1:], param_no)
                output += handle_function_sub(var_name, func_list[i], params) + "\n"
            if param_no < 0:  # functioncall
                params = find_param(func_list[i + 1:], abs(param_no) - 1)
                output += handle_function_fc(var_name, func_list[i], params) + "\n"

        else:
            for name in ud_functions:
                if func_list[i] == name:
                    param_no = ud_functions[func_list[i]]
                    params = find_param(func_list[i + 1:], abs(param_no) - 1)
                    output += handle_function_ud(var_name, func_list[i], params) + "\n"

    output = output.replace("\n", "\n" + chr(32) * indent)
    return output


def stringindent(x, lev):  # for indentation
    return chr(32) * lev + x + "\r\n"


def check_indent(list):
    output = ""
    if list[0] == "loop" or list[0] == "ud_function":
        output = True

    else:
        output = False

    return output


def create_param(param_list):
    parameter = ""
    for i in range(0, len(param_list)):
        parameter += param_list[i] + ","
    parameter = parameter[:-1]
    return parameter


indent = 0


def parser(list):
    global indent
    type_list = []  # contains type of data
    name_list = []  # value of data
    output = ""
    # new_output =""
    for i in range(0, len(list)):
        type_list.append(list[i][0])
        name_list.append(list[i][1])

    if type_list[0] == "variable":
        assign_list = []
        func_list = []
        var_name = name_list[0]
        store_index = 0
        if type_list[1]=='variable' or type_list[1]=="number" or type_list[1]=="string":
            assign_list.append(name_list[1])
            func_list = name_list[2:]
        else :
            func_list= name_list[1:]

        #print (func_list,assign_list)


        if len(assign_list) > 0 and len(func_list) == 0:  ## when no functions are used
            final_var = create_assign_var(var_name, assign_list)
            output = final_var

        if len(assign_list) == 0 and len(func_list) > 0:  ## when theres no assignment and functions are used
            output = create_func_var(var_name, func_list, indent)

        if len(assign_list) == 0 and len(func_list) == 0:  ## when theres no assignment and function call
            output = (var_name + " = 0 ")

        if len(assign_list)>0 and len(func_list)>0:
            output = create_assign_var(var_name,assign_list)+create_func_var(var_name,func_list,indent)



    if type_list[0] == "loop":
        output = ""
        if name_list[0] == "while":
            if len(name_list) > 1:
                print("error in syntax")
            else:
                output = "while True :"
                indent += 4
        if name_list[0] == "wend":
            indent -= 4
        if name_list[0] == "fig":
            indent -= 4
        if name_list[0] == "iftrue":
            rest_list = name_list[1:]
            if len(rest_list) != 1:
                print("syntax error")
            else:
                output = "if " + rest_list[0] + " == True :"
                indent += 4
        if name_list[0] == "ifequal":
            rest_list = name_list[1:]
            if len(rest_list) != 2:
                print("syntax error")
            else:
                output = "if " + rest_list[0] + " == " + rest_list[1] + " :"
                indent += 4
        if name_list[0] == "for":
            rest_list = name_list[1:]
            output = 'for ' + rest_list[0] + " in range(" + rest_list[1] + "," + rest_list[2] + "," + rest_list[
                3] + "):"
            indent += 4
        if name_list[0] == "forin":
            rest_list = name_list[1:]
            output = "for " + rest_list[0] + " in " + rest_list[1] + ":"
            indent += 4
        if name_list[0] == "else":
            if len(name_list) != 1:
                print("syntax error")
            else:
                output = "else:"
                indent += 4

    if type_list[0] == "ud_function":
        udfunction_name = name_list[1]
        params = create_param(name_list[2:])
        ud_functions[udfunction_name] = (-1 * len(name_list[2:])) - 1
        # print(udfunction_name,params)
        output = "def " + udfunction_name + "(" + params + "):"
        indent += 4

    if check_indent(type_list) == False:
        output = stringindent(output, indent)
    elif check_indent(type_list) == True:
        output = stringindent(output, indent - 4)

    return output


for line in lines:
    line = line.strip()
    if line == "":
        pass
    else:
        arr.append(line)

indexi=-2
pure_arr = []


for i in range(0, len(arr)):

    if arr[i].strip() == "python":
        pi = i
        #print(pi)
        for a in range(pi + 1, len(arr)):
            if arr[a].strip() == "fig":
                fi = a
                break
        pure_arr = arr[pi + 1:fi]
        #print(pure_arr)
        for b in range(0,len(pure_arr)):
            outfile.write(pure_arr[b]+"\n")

    else:
        output = (parser((lex(arr[i])))) + "\n"
        # print(output)
        outfile.write(output)




# output = create_func_var("var",["print","lcase","ucase"])
# print(output)
# print ud_functions

